import os
import time
import fcntl
import threading
import subprocess


class MPlayer (threading.Thread):
    done = False

    def __init__(self):
        threading.Thread.__init__(self)
        self.player = subprocess.Popen(['mplayer', '-slave', '-idle', '-really-quiet', '-msglevel', 'global=4'],
                                       shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
        self.song = ''
        self.cur_seconds = 0.0
        self.total_seconds = 0.0
        self.volume = 50.0
        self.status = 'INIT'
        self.codec = ''
        self.bitrate = ''
        self.samples = ''

    def pipe_read(self, pipe):
        fd = pipe.fileno()
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
        try:
            pipe.flush()
            ba = pipe.readline()
            s = ba.decode()
            return s
        except:
            return ''

    def player_cmd(self, cmd):
        cmd += '\n'
        self.player.stdin.write(cmd.encode())
        self.player.stdin.flush()

    def is_playing(self):
        return self.status == 'play'

    def load(self, file):
        self.song = file
        self.status = 'load'
        self.player_cmd('loadfile "' + file + '"')
        self.player_cmd('pausing_keep_force get_audio_codec')
        self.player_cmd('pausing_keep_force get_audio_bitrate')
        self.player_cmd('pausing_keep_force get_audio_samples')
        self.player_cmd('pausing_keep_force get_property length')
        self.set_volume(self.volume)

    def play(self):
        self.status = 'play'
        self.player_cmd('play')

    def pause(self):
        self.status = 'pause'
        self.player_cmd('pause')

    def stop(self):
        self.status = 'stop'
        self.player_cmd('stop')

    def quit(self):
        self.player_cmd('stop')
        self.player_cmd('quit')
        self.done = True

    def set_volume(self, vol):
        self.volume = vol
        self.player_cmd('pausing_keep_force set_property volume ' + str(vol))

    def get_status(self):
        return self.status

    def get_total_seconds(self):
        return self.total_seconds

    def get_current_seconds(self):
        return self.cur_seconds

    def set_current_seconds(self, seconds):
        self.player_cmd('pausing_keep_force seek ' + str(seconds) + ' 2')
        return self.cur_seconds

    def parse(self, cmd, value):
        if cmd == 'ANS_time_pos':
            cur_seconds = float(value)
            self.cur_seconds = cur_seconds
        elif cmd == 'ANS_AUDIO_CODEC':
            self.codec = value.replace("'", "")
            print(self.codec)
        elif cmd == 'ANS_AUDIO_BITRATE':
            self.bitrate = value.replace("'", "")
            print(self.bitrate)
        elif cmd == 'ANS_AUDIO_SAMPLES':
            self.samples = value.replace("'", "")
            print(self.samples)
        elif cmd == 'ANS_length':
            tot_seconds = float(value)
            self.total_seconds = tot_seconds
        elif value == 'PROPERTY_UNAVAILABLE':
            self.status = 'stop'

    def run(self):
        """
seek <value> [type]
    Seek to some place in the movie.
        0 is a relative seek of +/- <value> seconds (default).
        1 is a seek to <value> % in the movie.
        2 is a seek to an absolute position of <value> seconds.
stop
    Stop playback.
quit [value]
    Quit MPlayer. The optional integer [value] is used as the return code
    for the mplayer process (default: 0).
pause
    Pause/unpause the playback.
frame_step
    Play one frame, then pause again.
volume <value> [abs]
    Increase/decrease volume or set it to <value> if [abs] is nonzero.
mute [value]
    Toggle sound output muting or set it to [value] when [value] >= 0
    (1 == on, 0 == off).
loop <value> [abs]
    Adjust/set how many times the movie should be looped. -1 means no loop,
    and 0 forever.
loadlist <file> <append>
    Load the given playlist file, stopping playback of the current file.
    If <append> is nonzero playback continues and the playlist file is
    appended to the current playlist instead.
loadfile <file|url> <append>
    Load the given file/URL, stopping playback of the current file/URL.
    If <append> is nonzero playback continues and the file/URL is
    appended to the current playlist instead.
get_audio_bitrate
    Print out the audio bitrate of the current file.
get_audio_codec
    Print out the audio codec name of the current file.
get_audio_samples
    Print out the audio frequency and number of channels of the current file.
get_file_name
    Print out the name of the current file.
get_percent_pos
    Print out the current position in the file, as integer percentage [0-100).
get_time_length
    Print out the length of the current file in seconds.
get_time_pos
    Print out the current position in the file in seconds, as float.


get_audio_codec
ANS_AUDIO_CODEC='ffflac'
get_audio_bitrate
ANS_AUDIO_BITRATE='916 kbps'
get_audio_samples
ANS_AUDIO_SAMPLES='44100 Hz, 2 ch.'
get_file_name
ANS_FILENAME='01 - 백지영 - 잊지말아요.flac'
get_time_length
ANS_LENGTH=247.00
get_time_pos
ANS_TIME_POSITION=81.7


        """
        # Run your code here
        print('Start Player Thread')
        while not self.done:
            while True:
                s = self.pipe_read(self.player.stdout)
                if len(s) > 0:
                    cmd, value = s.split('=', 1)
                else:
                    break
                self.parse(cmd, value)
            if self.status == 'play':
                self.player_cmd('pausing_keep_force get_property time_pos')
            time.sleep(0.25)
        print('Player Stop!!')

